/* 
 *  Copyright (C) 2009-2010 milkyjing <milkyjing@gmail.com>
 *
 *  This Program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  This Program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *  http://www.gnu.org/copyleft/gpl.html
 *
 */

#include "tcsfunc.h"


TCX_Py_Error_Code tcxlib_tcs_list_append_pix(PyObject *self, PyObject *args) {
    PyObject *pyArg1, *pyArg2, *pyArg3, *pyArg4, *pyArg5, *pyArg6, *pyArg7;
    int start, end;
    double diffX, diffY;
    int layer;
    PyObject *tcsList;
    TCX_Pix pix;
    int w, h, index;
    unsigned long color;
    int alpha;
    int posX, posY, initPosX, initPosY;
    PyObject *pixDip;   /* store a dynamic isolated pixel of PIX temporary */
    if (PyTuple_GET_SIZE(args) < 7) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_main error, too less parameters - `(TCS_BUF, PIX, Start, End, DiffX, DiffY, Layer)'\n");
        return NULL;
    }
    pyArg1 = PyTuple_GET_ITEM(args, 0);
    if (!PyList_Check(pyArg1)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_main error, the 1st param should be a list - `TCS_BUF'\n");
        return NULL;
    }
    pyArg2 = PyTuple_GET_ITEM(args, 1);
    if (!PyTuple_Check(pyArg2)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_main error, the 2nd param should be a tuple - `PIX'\n");
        return NULL;
    }
    pyArg3 = PyTuple_GET_ITEM(args, 2);
    if (!PyLong_Check(pyArg3) && !PyFloat_Check(pyArg3)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_main error, the 3rd param should be an integer - `start'\n");
        return NULL;
    }
    pyArg4 = PyTuple_GET_ITEM(args, 3);
    if (!PyLong_Check(pyArg4) && !PyFloat_Check(pyArg4)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_main error, the 4th param should be an integer - `end'\n");
        return NULL;
    }
    pyArg5 = PyTuple_GET_ITEM(args, 4);
    if (!PyLong_Check(pyArg5) && !PyFloat_Check(pyArg5)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_main error, the 5th param should be a float - `initX'\n");
        return NULL;
    }
    pyArg6 = PyTuple_GET_ITEM(args, 5);
    if (!PyLong_Check(pyArg6) && !PyFloat_Check(pyArg6)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_main error, the 6th param should be a float - `initY'\n");
        return NULL;
    }
    pyArg7 = PyTuple_GET_ITEM(args, 6);
    if (!PyLong_Check(pyArg7) && !PyFloat_Check(pyArg7)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_main error, the 7th param should be an integer - `layer'\n");
        return NULL;
    }
    tcsList = pyArg1;    /* note: we needn't use Py_CLEAR(tcsList) or Py_INCREF(tcsList) */
    tcxlib_convert_py_pix((const TCX_PyPix)pyArg2, &pix);
    start = (int)PyLong_AsLong(pyArg3);
    end = (int)PyLong_AsLong(pyArg4);
    diffX = (double)PyFloat_AsDouble(pyArg5);
    diffY = (double)PyFloat_AsDouble(pyArg6);
    layer = (int)PyLong_AsLong(pyArg7);
    initPosX = (int)floor(diffX + pix.initX);    /* Note: no we don't use (int)(fDiffX + fInitX + 0.5) */
    initPosY = (int)floor(diffY + pix.initY);
    for (h = 0; h < pix.height; h ++) {
        posY = initPosY + h;
        for (w = 0; w < pix.width; w ++) {
            posX = initPosX + w;
            index = (h * pix.width + w) << 2;
            color = MAKERGB(pix.buf[index], pix.buf[index + 1], pix.buf[index + 2]);
            alpha = pix.buf[index + 3];
            if (0 != alpha) {
                pixDip = PyTuple_New(7);
                PyTuple_SET_ITEM(pixDip, 0, PyLong_FromLong(start));
                PyTuple_SET_ITEM(pixDip, 1, PyLong_FromLong(end));
                PyTuple_SET_ITEM(pixDip, 2, PyLong_FromLong(layer));
                PyTuple_SET_ITEM(pixDip, 3, PyLong_FromLong(posX));
                PyTuple_SET_ITEM(pixDip, 4, PyLong_FromLong(posY));
                PyTuple_SET_ITEM(pixDip, 5, PyLong_FromLong(color));
                PyTuple_SET_ITEM(pixDip, 6, PyLong_FromLong(alpha));
                PyList_Append(tcsList, pixDip);
                Py_CLEAR(pixDip);
            }
        }
    }
    free(pix.buf);
    return Py_BuildValue("i", 0);
}

TCX_Py_Error_Code tcxlib_tcs_list_append_pix_with_fade(PyObject *self, PyObject *args) {
    PyObject *pyArg1, *pyArg2, *pyArg3, *pyArg4, *pyArg5, *pyArg6, *pyArg7, *pyArg8, *pyArg9, *pyArg10;
    int start, end, t1, t2;
    double fps, diffX, diffY;
    int layer;
    PyObject *tcsList;
    TCX_Pix pix;
    int i, w, h, index, frame1, frame2;
    unsigned long color;
    int alpha;
    int posX, posY, initPosX, initPosY;
    PyObject *pixDip;   /* store a dynamic isolated pixel of PIX temporary */
    if (PyTuple_GET_SIZE(args) < 10) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_fade error, too less parameters - `(TCS_BUF, PIX, Start, End, t1, t2, fps, DiffX, DiffY, Layer)'\n");
        return NULL;
    }
    pyArg1 = PyTuple_GET_ITEM(args, 0);
    if (!PyList_Check(pyArg1)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_fade error, the 1st param should be a list - `TCS_BUF'\n");
        return NULL;
    }
    pyArg2 = PyTuple_GET_ITEM(args, 1);
    if (!PyTuple_Check(pyArg2)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_fade error, the 2nd param should be a tuple - `PIX'\n");
        return NULL;
    }
    pyArg3 = PyTuple_GET_ITEM(args, 2);
    if (!PyLong_Check(pyArg3) && !PyFloat_Check(pyArg3)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_fade error, the 3rd param should be an integer - `start'\n");
        return NULL;
    }
    pyArg4 = PyTuple_GET_ITEM(args, 3);
    if (!PyLong_Check(pyArg4) && !PyFloat_Check(pyArg4)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_fade error, the 4th param should be an integer - `end'\n");
        return NULL;
    }
    pyArg5 = PyTuple_GET_ITEM(args, 4);
    if (!PyLong_Check(pyArg5) && !PyFloat_Check(pyArg5)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_fade error, the 5th param should be an integer - `t1'\n");
        return NULL;
    }
    pyArg6 = PyTuple_GET_ITEM(args, 5);
    if (!PyLong_Check(pyArg6) && !PyFloat_Check(pyArg6)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_fade error, the 6th param should be an integer - `t2'\n");
        return NULL;
    }
    pyArg7 = PyTuple_GET_ITEM(args, 6);
    if (!PyLong_Check(pyArg7) && !PyFloat_Check(pyArg7)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_fade error, the 7th param should be a float - `fps'\n");
        return NULL;
    }
    pyArg8 = PyTuple_GET_ITEM(args, 7);
    if (!PyLong_Check(pyArg8) && !PyFloat_Check(pyArg8)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_fade error, the 8th param should be a float - `initX'\n");
        return NULL;
    }
    pyArg9 = PyTuple_GET_ITEM(args, 8);
    if (!PyLong_Check(pyArg9) && !PyFloat_Check(pyArg9)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_fade error, the 9th param should be a float - `initY'\n");
        return NULL;
    }
    pyArg10 = PyTuple_GET_ITEM(args, 9);
    if (!PyLong_Check(pyArg10) && !PyFloat_Check(pyArg10)) {
        PyErr_SetString(PyExc_RuntimeError, "tcs_fade error, the 10th param should be an integer - `layer'\n");
        return NULL;
    }
    tcsList = pyArg1;    /* note: we needn't use Py_CLEAR(tcsList) or Py_INCREF(tcsList) */
    tcxlib_convert_py_pix((const TCX_PyPix)pyArg2, &pix);
    start = (int)PyLong_AsLong(pyArg3);
    end = (int)PyLong_AsLong(pyArg4);
    t1 = (int)PyLong_AsLong(pyArg5);
    t2 = (int)PyLong_AsLong(pyArg6);
    fps = (double)PyFloat_AsDouble(pyArg7);
    diffX = (double)PyFloat_AsDouble(pyArg8);
    diffY = (double)PyFloat_AsDouble(pyArg9);
    layer = (int)PyLong_AsLong(pyArg10);
    frame1 = (int)(t1 * fps / 1000 + 0.5);
    frame2 = (int)(t2 * fps / 1000 + 0.5);
    initPosX = (int)floor(diffX + pix.initX);    /* Note: no we don't use (int)(fDiffX + fInitX + 0.5) */
    initPosY = (int)floor(diffY + pix.initY);
    for (i = 0; i < frame1; i ++) {
        for (h = 0; h < pix.height; h ++) {
            posY = initPosY + h;
            for (w = 0; w < pix.width; w ++) {
                posX = initPosX + w;
                index = (h * pix.width + w) << 2;
                color = MAKERGB(pix.buf[index], pix.buf[index + 1], pix.buf[index + 2]);
                alpha = pix.buf[index + 3];
                if (0 != alpha) {
                    pixDip = PyTuple_New(7);
                    PyTuple_SET_ITEM(pixDip, 0, PyLong_FromLong(start + (int)(i * 1000 / fps)));
                    PyTuple_SET_ITEM(pixDip, 1, PyLong_FromLong(start + (int)((i + 1) * 1000 / fps)));
                    PyTuple_SET_ITEM(pixDip, 2, PyLong_FromLong(layer));
                    PyTuple_SET_ITEM(pixDip, 3, PyLong_FromLong(posX));
                    PyTuple_SET_ITEM(pixDip, 4, PyLong_FromLong(posY));
                    PyTuple_SET_ITEM(pixDip, 5, PyLong_FromLong(color));
                    PyTuple_SET_ITEM(pixDip, 6, PyLong_FromLong(alpha * (i + 1) / frame1));
                    PyList_Append(tcsList, pixDip);
                    Py_CLEAR(pixDip);
                }
            }
        }
    }
    for (h = 0; h < pix.height; h ++) {
        posY = initPosY + h;
        for (w = 0; w < pix.width; w ++) {
            posX = initPosX + w;
            index = (h * pix.width + w) << 2;
            color = MAKERGB(pix.buf[index], pix.buf[index + 1], pix.buf[index + 2]);
            alpha = pix.buf[index + 3];
            if (0 != alpha) {
                pixDip = PyTuple_New(7);
                PyTuple_SET_ITEM(pixDip, 0, PyLong_FromLong(start + (int)(frame1 * 1000 / fps)));
                PyTuple_SET_ITEM(pixDip, 1, PyLong_FromLong(end - (int)(frame2 * 1000 / fps)));
                PyTuple_SET_ITEM(pixDip, 2, PyLong_FromLong(layer));
                PyTuple_SET_ITEM(pixDip, 3, PyLong_FromLong(posX));
                PyTuple_SET_ITEM(pixDip, 4, PyLong_FromLong(posY));
                PyTuple_SET_ITEM(pixDip, 5, PyLong_FromLong(color));
                PyTuple_SET_ITEM(pixDip, 6, PyLong_FromLong(alpha));
                PyList_Append(tcsList, pixDip);
                Py_CLEAR(pixDip);
            }
        }
    }
    for (i = frame2; i > 0; i --) {
        for (h = 0; h < pix.height; h ++) {
            posY = initPosY + h;
            for (w = 0; w < pix.width; w ++) {
                posX = initPosX + w;
                index = (h * pix.width + w) << 2;
                color = MAKERGB(pix.buf[index], pix.buf[index + 1], pix.buf[index + 2]);
                alpha = pix.buf[index + 3];
                if (0 != alpha) {
                    pixDip = PyTuple_New(7);
                    PyTuple_SET_ITEM(pixDip, 0, PyLong_FromLong(end - (int)(i * 1000 / fps)));
                    PyTuple_SET_ITEM(pixDip, 1, PyLong_FromLong(end - (int)((i - 1) * 1000 / fps)));
                    PyTuple_SET_ITEM(pixDip, 2, PyLong_FromLong(layer));
                    PyTuple_SET_ITEM(pixDip, 3, PyLong_FromLong(posX));
                    PyTuple_SET_ITEM(pixDip, 4, PyLong_FromLong(posY));
                    PyTuple_SET_ITEM(pixDip, 5, PyLong_FromLong(color));
                    PyTuple_SET_ITEM(pixDip, 6, PyLong_FromLong(alpha * i / frame2));
                    PyList_Append(tcsList, pixDip);
                    Py_CLEAR(pixDip);
                }
            }
        }
    }
    free(pix.buf);
    return Py_BuildValue("i", 0);
}

